//
//  CZStatusViewModel.swift
//  GZWeibo009
//
//  Created by gzxzmac on 16/3/25.
//  Copyright © 2016年 gzxzmac. All rights reserved.
//

import UIKit

import SDWebImage

class CZStatusViewModel: NSObject {
    // 单例
    static let sharedInstance: CZStatusViewModel = CZStatusViewModel()
    
    /// 1.是否在加载微博数据
    private var loading: Bool = false
    
    /**
     加载微博数据
     调用网络请求 API地址: http://open.weibo.com/wiki/2/statuses/home_timeline
     
     - parameter since_id:           若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0。
     - parameter max_id:             若指定此参数，则返回ID小于或等于max_id的微博，默认为0。
     - parameter loadStatusCallback: 获取到微博数据后的回调
     */
    func loadStatus(since_id: Int64, max_id: Int64, loadStatusCallback: (statuses: [CZStatus]?, error: NSError?) -> ()) {
        // 2.判断是否有人在加载微博数据
        if loading {
            CZPrint(msg: "有人正在在加载数据")
            // 告诉调用的人 有人正在加载微博数据
            // 自定义错误
            // domain: 域,自定义,主要表示错误的范围
            // code: 自定义: 表示错误的类型
            // userInfo: 错误的附加信息:
            let error = NSError(domain: "cn.ken.error.net.status", code: -1, userInfo: ["errorDescription" : "嘿哥们,手不要那么快,重复刷新了"])
            loadStatusCallback(statuses: nil, error: error)
            return
        }
        
        // 3.之间没有人加载
        loading = true
        
        // url
        let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
        
        // 请求参数
        var parameters: [String:AnyObject] = ["access_token": CZUserAccountViewModel.sharedInstance.userAccount!.access_token!]
        
        // 表示别人传递了 since_id需要下拉刷新,返回比 since_id 大的微博
        if since_id > 0 {
            parameters["since_id"] = NSNumber(longLong: since_id)
        } else if max_id > 0 {
            // 比人传递了max_id.添加到字典里面
            parameters["max_id"] = NSNumber(longLong: max_id - 1)
        }
        
        // 发送get 请求获取数据
        CZNetworkTool.sharedInstance.requestGET(urlString, parameters: parameters) { (result, error) -> () in
            
            // 4 微博数据加载完成,将 loading改成false,以便再次可以调用
            self.loading = false
            
            if error != nil {
                // 出现了错误
                loadStatusCallback(statuses: nil, error: error)
                return
            }
            
            // 没有出错,解析返回的数据中的 "statuses", statuses里面对应的是所有的微博数据
            // [[String: AnyObject]]: 数组,数组里面存的是字典类型的元素
            let statusesArray = result?["statuses"] as? [[String: AnyObject]]
            
            // 定义空数组来存放微博模型
            var statuses = [CZStatus]()
            
            // 遍历微博字典数组
            for dict in statusesArray! {
                // 字典转模型
                let status = CZStatus(dict: dict)
                statuses.append(status)
            }
            
            // 当字典转模型完成后,来缓存微博模型里面的图片,当微博里面的图片缓存完成了,才通知控制器来显示微博数据
            self.cacheWebImage(statuses, loadStatusCallback: loadStatusCallback)
            
            // 字典转模型完成了,通知控制器来显示微博数据
            //            loadStatusCallback(statuses: statuses, error: nil)
        }
    }
    
    /// 缓存微博图片
    private func cacheWebImage(statuses: [CZStatus], loadStatusCallback: (statuses: [CZStatus]?, error: NSError?) -> ()) {
        // 创建group
        let group = dispatch_group_create()
        
        var length: CGFloat = 0
        
        // 查找微博里面的图片,下载下来
        for status in statuses {
            var downloadURLs = status.storePictureURLs
            
            // 如果原创没有,找转发的微博
            if downloadURLs == nil {
                downloadURLs = status.retweeted_status?.storePictureURLs
            }
            
            if downloadURLs == nil {
                // 说明原创没有图片,被转发的也没有图片
                continue
            }
            
            // 能到下面来说明有图片需要下载,不管微博模型里面有几张图片都缓存,会导致缓存图片时间太长了.
            // 只需要缓存一张图片,多张图片的不需要管,可要在cell即将显示的时候SDWebImage会自己去下载
            if downloadURLs?.count == 1 {
                let url = downloadURLs![0]
                //            for url in downloadURLs! {
                // 使用SDWebImage下载图片,downloadImageWithURL是异步的方法,会将下载的图片保存在沙盒中,图片的名称是urlString MD5编码
                // 在异步任务之前进入组
                dispatch_group_enter(group)
                SDWebImageManager.sharedManager().downloadImageWithURL(url, options: SDWebImageOptions(rawValue: 0), progress: nil, completed: { (image, error, _, _, _) -> Void in // SDWebImage下载完成图片的时候的回调
                    // 不管是下载成功还是失败,任务都完成了.就需要离开组
                    dispatch_group_leave(group)
                    
                    if error != nil {
                        CZPrint(msg: "SDWebImageManager下载图片失败: \(url)")
                        return
                    }
                    
                    CZPrint(msg: "下载图片成功了: \(url)")
                    let data = UIImagePNGRepresentation(image)!
                    length += CGFloat(data.length)
                })
            }
        }
        
        // 所有模型的图片都下载完成才通知我
        dispatch_group_notify(group, dispatch_get_main_queue()) { () -> Void in
            let len = length / 1024 / 1024.0
            let l = String(format: "%.2f", arguments: [len])
            print("所有图片都缓存完成: \(l) MB")
            
            // 所有图片都缓存完成,通知控制器来显示微博数据
            loadStatusCallback(statuses: statuses, error: nil)
        }
    }
}
